package com.mallbook.controller.servlet.front;

import com.alipay.api.FileItem;
import com.mallbook.controller.filter.AdminFilter;
import com.mallbook.model.exception.*;
import com.mallbook.model.pojo.Goods;
import com.mallbook.model.pojo.Orders;
import com.mallbook.model.pojo.User;
import com.mallbook.model.service.OrderService;
import com.mallbook.model.service.UserService;
import com.mallbook.model.utils.MD5Utils;
import com.mallbook.model.utils.MallDefaultConfig;
import com.sun.xml.internal.bind.v2.TODO;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
 * @Author 宋明松
 * @Version V1.0.0
 * @Date 2022-07-04
 */
@WebServlet("/user")
@MultipartConfig
public class UserServlet extends HttpServlet {
    private static final Logger logger = LoggerFactory.getLogger(UserServlet.class);
    private UserService userService = new UserService();
    private OrderService orderService = new OrderService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String opr = req.getParameter("opr");
        switch (opr) {
            case "register":
                doInit(req, resp);
                break;
            case "login":
                doLogin(req, resp);
                break;
            case "goLogin":
                doGoLogin(req, resp);
                break;
            case "logout":
                doLoginOut(req, resp);
                break;
            case "reg":
                doRegister(req, resp);
                break;
            case "active":
                doActive(req, resp);
                break;
            case "select":
                doSelect(req, resp);
                break;
            case "check":
                doCheck(req, resp);
                break;
            case "update":
                doUpdate(req, resp);
                break;
        }
    }

    /**
     * 用户更新
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void doUpdate(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        HttpSession session = req.getSession();
        JSONObject jsonObject = new JSONObject();
        PrintWriter writer = resp.getWriter();
        if (session.getAttribute("USER") == null) {
            jsonObject.put("msg", "用户未登录");
            writer.print(jsonObject);
            writer.close();
            return;
        }
        String pwd = req.getParameter("pwd");// 密码
        String type = req.getParameter("type");// 修改类型，1表示只修改密码 ,2代表修改头像
        logger.info("修改TYPE{}", type);
        User u = (User) session.getAttribute("USER");
        if ("1".equals(type)) {
            logger.info("用户{}开始修改密码", u.getUsername());
            if (pwd == null || pwd.trim().isEmpty()) {
                jsonObject.put("msg", "密码不能为空");
                writer.print(jsonObject);
                writer.close();
                return;
            }
        }

        String DBPath = null;
        if ("2".equals(type)) {
            logger.info("用户{}开始修改头像", u.getUsername());
            // 获取提交上来的头像
            Part part = req.getPart("file");
            // 原文件名在头信息的Content-Disposition中
            // Content-Disposition:form-data; name="photo"; filename="测试文件.txt"
            String header = part.getHeader("Content-Disposition");
            // 获取原文件名
            int start = header.lastIndexOf("=") + 1;
            String name = header.substring(start).replace("\"", "");
            logger.info("头像文件名{}", name);
            // 获取文件后缀名
            String suffix = name.substring(name.lastIndexOf("."));
            // 获取站点文件存放路径
            String path = getServletContext().getRealPath("/userImg");
            // 产生一个32位的唯一字符串生成随机文件名
            String fileName = UUID.randomUUID().toString().replace("-", "");
            logger.info("获取站点文件存放路径{}", path);
            logger.info("头像存放路径：{}", path + "/" + fileName + suffix);
            // 删除原来的图片文件
            // 不是是默认头像

            logger.info("默认头像{}", MallDefaultConfig.USER_IMG);
            // 查询用户数据库中的头像
            User DBu = userService.getUser(u.getId());
            logger.info("用户头像{}", DBu.getImg());
            if (!DBu.getImg().equals(MallDefaultConfig.USER_IMG)) {
                String delPath = getServletContext().getRealPath("/") + DBu.getImg();
                logger.info("开始删除头像{}", delPath);
                File delFile = new File(delPath);
                if (!delFile.delete()) {
                    jsonObject.put("msg", "头像更新失败");
                    writer.print(jsonObject);
                    writer.close();
                    return;
                }
            }
            logger.info("开始写入磁盘{}", path + "/" + fileName + suffix);
            // 将文件写入磁盘
            part.write(path + "/" + fileName + suffix);
            DBPath = "userImg/" + fileName + suffix;
        }
        try {
            logger.info("用户{}新头像地址{}", u.getUsername(), DBPath);
            userService.updateUser(pwd, null, null, DBPath, u.getId());
            jsonObject.put("msg", "ok");
            jsonObject.put("img", DBPath);
            writer.print(jsonObject);
            writer.close();
        } catch (EmailExitsException e) {
            jsonObject.put("msg", "邮箱已被使用");
            writer.print(jsonObject);
            writer.close();
        } catch (ServiceException e) {
            e.printStackTrace();
            jsonObject.put("msg", "系统繁忙，请稍后再试");
            logger.info("用户{}修改失败", u.getUsername());
            writer.print(jsonObject);
            writer.close();
        }
    }

    /**
     * 账号密码邮箱及时验证
     *
     * @param req
     * @param resp
     */
    private void doCheck(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String email = req.getParameter("email");
        HttpSession session = req.getSession();
        JSONObject jsonObject = new JSONObject();
        PrintWriter writer = resp.getWriter();
        // 个人中心修改密码原密码验证
        if (session.getAttribute("USER") != null) {
            String pwd = req.getParameter("pwd");
            User u = (User) session.getAttribute("USER");
            try {
                User DBUser = userService.getUser(u.getId());
                if (MD5Utils.stringToMD5(pwd).equals(DBUser.getPassword())) {
                    jsonObject.put("msg", "ok");
                } else {
                    jsonObject.put("msg", "密码错误");
                }
            } catch (ServiceException e) {
                jsonObject.put("msg", "系统繁忙，请稍后再试");
            }

        } else if (username != null) { // 注册时:账号及时验证
            User user = new User();
            user.setUsername(username);
            try {
                userService.checkInfo(user);
                jsonObject.put("msg", "ok");
            } catch (EmailExitsException e) {
                e.printStackTrace();
                jsonObject.put("msg", "邮箱已被使用");
            } catch (AccountExitsException e) {
                e.printStackTrace();
                jsonObject.put("msg", "用户名已存在");
            } catch (ServiceException e) {
                e.printStackTrace();
                jsonObject.put("msg", "系统繁忙，请稍后再试");
            }

        } else if (email != null) {// 注册时:邮箱及时验证
            User user = new User();
            user.setEmail(email);
            try {
                userService.checkInfo(user);
                jsonObject.put("msg", "ok");
            } catch (EmailExitsException e) {
                jsonObject.put("msg", "邮箱已存在");
            } catch (AccountExitsException e) {
                jsonObject.put("msg", "用户名已存在");
            } catch (ServiceException e) {
                jsonObject.put("msg", "系统繁忙，请稍后再试");
            }
        }
        writer.print(jsonObject);
        writer.close();
    }

    /**
     * 个人中心展示页面
     *
     * @param req
     * @param resp
     */
    private void doSelect(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        HttpSession session = req.getSession();
        User u = (User) session.getAttribute("USER");
        PrintWriter writer = resp.getWriter();
        try {
            logger.info("用户{}开始访问个人中心", u.getUsername());
            logger.info("开始获取{}账号信息", u.getUsername());
            User user = userService.getUser(u.getId());

            // 存入json格式数据
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("username", user.getUsername());
            jsonObject.put("email", user.getEmail());
            jsonObject.put("regTime", user.getRegTime());
            jsonObject.put("state", user.getState());
            jsonObject.put("integral", user.getIntegral());
            jsonObject.put("img", user.getImg());
            jsonObject.put("id", user.getId());
            logger.info("开始获取{}账号订单信息", u.getUsername());
            String[] info = orderService.getUcenterOrderDetailNums(u.getId());
            jsonObject.put("allOrderNums", info[0]);
            jsonObject.put("allMoney", info[1]);
            jsonObject.put("notEvaluateNums", info[2]);
            jsonObject.put("notGetMoneyNums", info[3]);
            jsonObject.put("notConfirmNums", info[4]);
            writer.print(jsonObject);
            writer.close();
        } catch (ServiceException e) {
            logger.info("用户{}开始访问个人中心出错！！！", u.getUsername());
            e.printStackTrace();
            writer.print("系统维护中");
            writer.close();
        }

    }

    /**
     * 邮箱验证
     *
     * @param req
     * @param resp
     */
    private void doActive(HttpServletRequest req, HttpServletResponse resp) {
        // TODO: 2022-07-08 邮箱验证
        String email = req.getParameter("email");
    }

    private void doRegister(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String captcha = req.getParameter("captcha");
        if (req.getSession().getAttribute("captcha") == null) {
            resp.sendRedirect("captcha");
            return;
        }
        String captchaSession = (String) req.getSession().getAttribute("captcha");
        if (!captcha.equalsIgnoreCase(captchaSession)) {
            req.setAttribute("msg", "验证码错误");
            req.getRequestDispatcher("/WEB-INF/front/registe.jsp").forward(req, resp);
            return;
        }

        String name = new String(req.getParameter("account").getBytes("iso8859-1"), StandardCharsets.UTF_8);
        String pwd = req.getParameter("password");
        String email = req.getParameter("email");
        if (name.trim().isEmpty() || pwd.trim().isEmpty() || email.trim().isEmpty()) {
            req.setAttribute("msg", "不能输入空字符串，以及空格");
            return;
        }
        try {
            userService.register(name, pwd, email);
            resp.sendRedirect("/user?opr=login");
        } catch (EmailExitsException e) {
            e.printStackTrace();
            req.setAttribute("msg", "邮箱已存在");
            req.getRequestDispatcher("/WEB-INF/front/registe.jsp").forward(req, resp);
        } catch (AccountExitsException e) {
            e.printStackTrace();
            req.setAttribute("msg", "用户名已存在");
            req.getRequestDispatcher("/WEB-INF/front/registe.jsp").forward(req, resp);
        } catch (ServiceException e) {
            e.printStackTrace();
            req.setAttribute("msg", "系统繁忙，请稍后再试");
            req.getRequestDispatcher("/WEB-INF/front/registe.jsp").forward(req, resp);
        }
    }

    private void doLoginOut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("USER");
        resp.sendRedirect("/index");
    }

    private void doGoLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = new String(req.getParameter("account").getBytes("iso8859-1"), StandardCharsets.UTF_8);
//        String username=req.getParameter("account");
        String password = req.getParameter("password");
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        HttpSession session = req.getSession();
        session.setAttribute("userMsg", user);
        if (username.trim().isEmpty()) {
            req.setAttribute("msg", "账号无效");
            req.getRequestDispatcher("/WEB-INF/front/login.jsp").forward(req, resp);
            return;
        }
        if (password.trim().isEmpty()) {
            req.setAttribute("msg", "密码无效");
            req.getRequestDispatcher("/WEB-INF/front/login.jsp").forward(req, resp);
            return;
        }
        try {
            User u = userService.login(username, password);
            session.setAttribute("USER", u);
            String referer = req.getParameter("returnURL");
            logger.info("goLogin:returnURL{}:" + referer);
            if (referer != null && !referer.isEmpty()) {
                if (!"http://127.0.0.1:8080/user?opr=register".equals(referer)) {
                    resp.sendRedirect("/index");
                }else {
                    resp.sendRedirect(referer);
                }

            } else {
                resp.sendRedirect("/index");
            }

        } catch (AccountNotExitsException e) {
            e.printStackTrace();
            req.setAttribute("msg", "账号不存在");
            req.getRequestDispatcher("/WEB-INF/front/login.jsp").forward(req, resp);
        } catch (AccountPwdErrorException e) {
            e.printStackTrace();
            req.setAttribute("msg", "密码错误");
            req.getRequestDispatcher("/WEB-INF/front/login.jsp").forward(req, resp);
        } catch (AccountBanException e) {
            e.printStackTrace();
            req.setAttribute("msg", "您的账号被禁止登录");
            req.getRequestDispatcher("/WEB-INF/front/login.jsp").forward(req, resp);
        } catch (ServiceException e) {
            e.printStackTrace();
            req.setAttribute("msg", "系统维护中");
            req.getRequestDispatcher("/WEB-INF/front/login.jsp").forward(req, resp);
        }
    }

    private void doLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String referer = req.getHeader("referer");
        logger.info("doLogin:referer{}:" + referer);
        req.setAttribute("referer", referer);
        req.getRequestDispatcher("/WEB-INF/front/login.jsp").forward(req, resp);
    }

    private void doInit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/WEB-INF/front/registe.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
